package dao;

import model.GoodsType;
import util.*;

import java.math.BigInteger;
import java.sql.SQLException;
import java.util.List;

/**
 * 商品类型信息管理模块DAO
 * author 朱以学文
 * 修订 by 兰彦真
 */
public class GoodsTypesManager implements GoodsTypesManagerment {

    /**
     * 新增一个商品类型
     * @param gtyp 包含新商品类型信息的对象
     * @return 新类型在数据库中的id
     */
    @Override
    public Long insertOne(GoodsType gtyp) {
        try {
            //从连接池获取一个数据库连接
            JDBCConnection conn = JDBCFactory.takeJDBC();
            //执行插入，得到主键id
            Long gKey = ((BigInteger) conn.updateForGeneratedKey("insert into t_gtypes values(null,?,?)", gtyp.getGtyp_tag(), gtyp.getGtyp_descript())).longValue();
            //归还连接
            JDBCFactory.returnBack(conn);
            //返回主键id
            return gKey;
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return null;
        }
    }

    /**
     * 更改一个商品类型的信息
     * @param gtyp 所要更改的商品类型，必须指定一个 id 或 tag，其余可以留null
     * @param desti 目的修改数据，不修改的字段留 null，id 不可修改，将被忽略
     * @return 修改成功返回true，否则返回false
     */
    @Override
    public boolean updateOne(GoodsType gtyp, GoodsType desti) {
        //判空
        if(gtyp == null  ||  desti == null  ||  gtyp.getGtyp_id() == null && Common.isStringEmpty(gtyp.getGtyp_tag())
                || Common.isStringEmpty(desti.getGtyp_tag()) && Common.isStringEmpty(desti.getGtyp_descript())
        ) return false;

        boolean firstArg = true;

        //sql查询语句母体
        String sql = "update t_mtypes set";

        String sql_condition = null;

        //sql语句更新字段参数拼接字符串
        StringBuilder sql_args = new StringBuilder();

        //sql操作更新的实参列表
        ArgsList<Object> args = new ArgsList<>();

        //若设定了对 tag 的修改
        if(!Common.isStringEmpty(desti.getGtyp_tag())) {
            //拼接新的 sql 更新字段
            if(!firstArg) sql_args.append(',');
            sql_args.append(" gtyp_tag = ?");
            //添加实参到列表
            args.add(desti.getGtyp_tag());
            firstArg = false;
        }

        //若设定了对 descript 的修改
        if(!Common.isStringEmpty(desti.getGtyp_descript())) {
            if(!firstArg) sql_args.append(',');
            sql_args.append(" gtyp_descript = ?");
            args.add(desti.getGtyp_descript());
            firstArg = false;
        }

        //若不知道类别的id，按类别名称获取id
        if(gtyp.getGtyp_id() != null) {
            sql_condition = " where gtyp_id = ?";
            args.add(gtyp.getGtyp_id());
        } else {
            sql_condition = " where gtyp_tag = ?";
            args.add(gtyp.getGtyp_tag());
        }

        try {
            //更新记录
            JDBCConnection conn = JDBCFactory.takeJDBC();
            int count = conn.update(args, "update t_gtypes set" + sql_args.toString() + sql_condition);
            JDBCFactory.returnBack(conn);

            return count == 1;
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return false;
        }
    }

    /**
     * 删除商品类型 (会删除商品的目的类型属性，但会保留该商品和其它类型属性)
     * @param gtyp 要删除的类型
     * @return 受影响的商品个数
     */
    @Override
    public int deleteOne(GoodsType gtyp) {
        //判空
        if(gtyp == null  ||  gtyp.getGtyp_id() == null && Common.isStringEmpty(gtyp.getGtyp_tag())) return 0;
        Long gtypID = null;

        try {
            //从连接池获取一个数据库连接
            JDBCConnection conn = JDBCFactory.takeJDBC();
            //开启事务
            conn.start();

            //若不知道类别的id，按类别名称获取id
            if ((gtypID = gtyp.getGtyp_id()) == null) {
                List<Object[]> tmp = conn.query("select gtyp_id from t_gtypes where gtyp_tag = ?", gtyp.getGtyp_tag());

                //未找到该名称的消息类型
                if (tmp.size() == 0) {
                    //回滚事务
                    conn.rollback();
                    //归还连接
                    JDBCFactory.returnBack(conn);
                    return 0;
                }
                gtypID = (Long) JDBCConnection.getGeneratedKey(tmp);
            }

            //删除物品与该类型的关联
            int count = conn.update("delete from t_goodsoftype where gtyp_id = ?", gtypID);
            //删除该类型
            conn.update("delete from t_gtypes where gtyp_id = ?", gtypID);

            //提交事务
            conn.commit();
            //归还连接
            JDBCFactory.returnBack(conn);
            return count;
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return 0;
        }
    }

    /**
     * 包装并返回查询到的对象的列表
     * @param list 包含 SQL 行查询结果的列表，Object[]中每一项都是一列的值
     * @return 返回包装好的对象列表
     */
    private static List<GoodsType> getResultList(List<Object[]> list)
    {
        GoodsType gTyp = null;

        List<GoodsType> result = new ResultList<>();

        for(Object[] row : list)
        {
            gTyp = new GoodsType();

            gTyp.setGtyp_id((Long) row[0]);
            gTyp.setGtyp_tag((String) row[1]);
            gTyp.setGtyp_descript((String) row[2]);

            result.add(gTyp);
        }
        return result;
    }

    @Override
    public List<GoodsType> queryAll(int pageSize, int page) {
        try {
            JDBCConnection conn = JDBCFactory.takeJDBC();
            List<Object[]> list = conn.query("select * from t_gtypes limit ?, ?", (page - 1) * pageSize, pageSize);
            JDBCFactory.returnBack(conn);
            if (list.isEmpty()) return null;
            return getResultList(list);
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return null;
        }
    }

    @Override
    public GoodsType queryByName(String name) {
        try {
            JDBCConnection conn = JDBCFactory.takeJDBC();
            List<Object[]> list = conn.query("select * from t_gtypes where gtyp_tag = ?", name);
            JDBCFactory.returnBack(conn);
            if (list.isEmpty()) return null;
            return getResultList(list).get(0);
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return null;
        }
    }

    @Override
    public GoodsType queryByID(Long id) {
        try {
            JDBCConnection conn = JDBCFactory.takeJDBC();
            List<Object[]> list = conn.query("select * from t_gtypes where gtyp_id = ?", id);
            JDBCFactory.returnBack(conn);
            if (list.isEmpty()) return null;
            return getResultList(list).get(0);
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return null;
        }
    }

    /**
     * 获取或创建一个商品类型
     * @param name 类型名，不可为null
     * @param descript 如果类型不存在，创建类型时指定的类型描述，可为null
     * @return 类型的id，失败返回null
     */
    @Override
    public Long getGoodsType(String name, String descript) {
        if(name == null) return null;
        GoodsType typ = queryByName(name);
        if(typ == null) {
            typ.setGtyp_id(insertOne(typ = (new GoodsType(null, name, descript))));
        }

        return typ.getGtyp_id();
    }
}

